package com.yh.service.impl;

import com.github.pagehelper.PageHelper;
import com.yh.mapper.UserMapper;
import com.yh.pojo.UserInfo;
import com.yh.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import com.yh.pojo.Role;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author by 张晨光
 * @date 2023/11/6 10:54
 */
@Service
public class UserServiceImpl implements UserService {
    //依赖注入;DI
    @Resource
    UserMapper userMapper;

    //延迟
    @Lazy
    @Resource
    PasswordEncoder passwordEncoder;

    /**
     * 根据用户名来获取，用户相关信息;
     * 对于返回类型是UserDetails接口，需要获取接口的实现类的对象;
     * 其实现类：User类;
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //通过mapper,来获取返回的userInfo对象;
        UserInfo userInfo = userMapper.findUserByUserName(username);
        //定义一个User对象;
        User user=null;

        if(userInfo!=null){
            //创建一个泛型集合，存储凭证信息
            List<SimpleGrantedAuthority>simpleGrantedAuthorities=new ArrayList<>();
            //获取userInfo对应的所有的角色集合;
            List<Role>roles=userInfo.getRoles();
            //下面使用循环，将角色集合存储上述的泛型集合里面;
            for (Role role : roles) {
                //存储每一个SimpleGrantedAuthority对象
                //System.out.println("对应的角色："+role.getRoleName());
                //这个时候，去对照笔记.
                //本质上是和这个类，RoleVoter，有关，这个类的前缀，必须是：ROLE_
                simpleGrantedAuthorities.add(new SimpleGrantedAuthority("ROLE_"+role.getRoleName()));
            }

            user=new User(userInfo.getUsername(),
                      userInfo.getPassword(),
                      userInfo.getStatus()==0?false:true,
                      true,             //账号不过期
                      true,                             //凭证不过期
                      true,                             //锁定不过期
                     simpleGrantedAuthorities
                    );
        }
        //System.out.println(userInfo.getUsername());
       // System.out.println(userInfo.getRoles());
        return user;
    }

    @Override
    public List<UserInfo> findAllUsers() {
        return userMapper.findAllUsers();
    }

    @Override
    public void save(UserInfo userInfo) {
        //将加密后的密码，放进去;
        userInfo.setPassword(passwordEncoder.encode(userInfo.getPassword()));
        userMapper.save(userInfo);
    }

    @Override
    public UserInfo findUserById(Integer id) {
        return userMapper.findUserById(id);
    }

    @Override
    public UserInfo findSimpleUserById(Integer id) {
        return userMapper.findSimpleUserById(id);
    }

    @Override
    public List<Role> findOtherRoles(Integer id) {
        return userMapper.findOtherRoles(id);
    }

    /**
     *  将笔记上的Integer[]rds,Integer...rds,可变参
     * @param userid
     * @param rds
     */
    @Override
    public void addRoleToUser(Integer userid, Integer ... rds) {
        if(rds!=null){
            for (Integer roleid : rds) {
                userMapper.addRoleToUser(userid,roleid);
            }
        }

    }

    /**
     * 业务层调用dao/mapper层的增删改的时候，注意：
     * 有多个增删改，加事务；
     * 查询+增删改，加事务；
     * 隔离级别:4; 读UnCommited ReadCommited     RepeatAble(默认mysql级别)   可串行化（效率最低，安全性最高)
     * @param id
     */
    @Transactional
    @Override
    public void deleteUser(Integer id) {
        userMapper.deleteUserRoleById(id);
        userMapper.deleteUserById(id);
    }
}
